/* $RCSFile: CrmInputAccount.ascx.cs $
 * Apache license v2 2011 by Christian Surieux
 * $Source: ?/AddonNice/PageModules/CrmInputAccount/CrmInputAccount.ascx.cs $
 * $log$
 * Revision 20 2010/08/09 10:51:19  christian.surieux
 *   Added Log comment to all .aspx .ascx .master files
 * Revision 19 2010/08/09 09:43:49  christian.surieux
 *   Added Log to cs sources files
 * Revision 6 2010/08/06 19:56:24  christian.surieux
 *   Added Log to All cs files
 */

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;  
using System.Web.UI.WebControls;
using System.Diagnostics;
using System.Drawing;
using System.Data.SqlClient;
using System.Web.Services.Protocols;
using System.Globalization;

using AddonNice.UI;
using AddonNice.Design;
using AddonNice.UI.WebControls;
using AddonNice.Security;
using AddonNice.UI.DataTypes;
using AddonNice.Configuration;
using AddonNice.Configuration.Settings;
using AddonNice.Diagnostics;
using AddonNice.Helpers;
using AddonNice.Settings;

using AddonNice.CRMWrapper;
using CrmSdk;

using Trace2    =   System.Diagnostics.Trace;

namespace AddonNice.PageModules.CrmInputAccount
{
    public class AStr
    {
        public const string EmailMandatory           =   "ACCOUNT_INPUT_CHECKEMAIL";
        public const string AddressMandatory         =   "ACCOUNT_INPUT_CHECKADDRESS";
        public const string CrmInputAccountOwner     =   "ACCOUNT_INPUT_OWNER";
        public const string AutoCreateCompany        =   "ACCOUNT_INPUT_PARENT";
        public const string AutoCreatePrimaryContact =   "ACCOUNT_INPUT_AUTOPRIMARYCONTACT";
        public const string AssignToOwner            =   "ACCOUNT_INPUT_OWNER_ATTRIBUTE";
        public const string AutoGen                  =   "ACCOUNT_INPUT_AUTOGEN";

    }

    /// <summary>
    /// Initializer class for CrmInputAccount 
    /// </summary>
    public class CrmInputAccountSI : PortalCRMModuleControlSI
    {
        public CrmInputAccountSI(ModuleSettingsDictionary bSettings,ISettingsOwner pm) : base()
        {
            if ( ModuleTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]CrmInputAccountSI Ctor BEG.",ModuleTraceSwitch.Sw.Info);
            InitSettings(bSettings,pm);
            if ( ModuleTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]CrmInputAccountSI Ctor END.",ModuleTraceSwitch.Sw.Info);
        }
 
        public override void InitSettings(ModuleSettingsDictionary bSettings,ISettingsOwner pm)
        {             
            if ( ModuleTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( "[V]CrmInputAccountSI InitSettings BEG.",ModuleTraceSwitch.Sw.Info);
            
            base.InitSettings(bSettings,pm);

			// Specific parameters
            const string resFile	                    =	"CrmInputAccount";
            string extgrp                               =   pm.ExtendedResourcesGroup;
            
            SettingItemSpecial AttributeOwner           =   new SettingItemSpecial(AStr.AssignToOwner,new BooleanDataType());
            AttributeOwner.Required                     =   false;
			AttributeOwner.ResourceFile                 =   resFile;
            AttributeOwner.Value                        =   StStr.strFalse;
            AttributeOwner.Order                        =   10;
            AttributeOwner.ExtendedGroupName            =   extgrp;
            AttributeOwner.EnglishName                  =   "Assign to Owner";
            AttributeOwner.Description                  =   "When checked, the new crm Account will be automatically assigned to selected owner";
            bSettings.AddSetting(AttributeOwner);

            WSListDataType defAcc                       =   new WSListDataType(CrmStr.systemuser,StStr.smName,StStr.bgID);
            SettingItemSpecial ModuleOwner              =   new SettingItemSpecial(AStr.CrmInputAccountOwner,defAcc);
            ADNDynSystemUser wsys                       =   null;
            if (!string.IsNullOrEmpty(Config.CRMDefaultAccount))
            {
                string domainName                       =   string.Format("{0}\\{1}",Config.CRMDefaultAccountDomain,Config.CRMDefaultAccount);
                wsys                                    =   Wrapper.Util.FindSystemUserByDomainName(domainName);
            }
            else 
            {
                wsys                                    =   DynEntity.GetFromCache<ADNDynSystemUser>(CrmStr.systemuser,Wrapper,new ResetWrapperHandler(ResetWrapper),Wrapper.adminUserId);
            }
            if (wsys != null)
            {       
                ModuleOwner.Value                       =   wsys.systemuserid.ToString();
                defAcc.DisplayTextValue                 =   wsys.fullname;
            }
            ModuleOwner.EnglishName                     =   "Owner";
            ModuleOwner.ResourceFile                    =   resFile;
            ModuleOwner.Order                           =   20;
            ModuleOwner.ExtendedGroupName               =   extgrp;
            ModuleOwner.Description                     =   " Choose the owner for Accounts created with this module if specified by previous checkbox";
            ModuleOwner.SettingItemsEvent               +=  new SettingItemsEventHandler(ModuleOwner_SettingItemsEvent);
            bSettings.AddSetting(ModuleOwner);

            // Input Email for this Account 
            SettingItemSpecial EmailMandatory           =   new SettingItemSpecial(AStr.EmailMandatory,new BooleanDataType());
            EmailMandatory.Required                     =   false;
            EmailMandatory.ResourceFile                 =   resFile;  
            EmailMandatory.Value                        =   StStr.strFalse;
            EmailMandatory.Order                        =   30;
            EmailMandatory.ExtendedGroupName            =   extgrp;
            EmailMandatory.EnglishName                  =   "Email needed ";
            EmailMandatory.Description                  =   "When checked email is required for new Account";
            bSettings.AddSetting(EmailMandatory);

            //  Input Address for this Account
            SettingItemSpecial AddressMandatory         =   new SettingItemSpecial(AStr.AddressMandatory,new BooleanDataType());
            AddressMandatory.Required                   =   false;
            AddressMandatory.ResourceFile               =   resFile;
            AddressMandatory.Value                      =   StStr.strFalse;
            AddressMandatory.Order                      =   40;
            AddressMandatory.ExtendedGroupName          =   extgrp;
            AddressMandatory.EnglishName                =   "Address needed";
            AddressMandatory.Description                =   "When checked Address fields are required for this Account";
            bSettings.AddSetting(AddressMandatory);

            // to create the nonexisting companies automatically
            SettingItemSpecial AutoCreateCompany        =   new SettingItemSpecial(AStr.AutoCreateCompany,new BooleanDataType());
            AutoCreateCompany.Required                  =   false;
            AutoCreateCompany.ResourceFile              =   resFile;
            AutoCreateCompany.Value                     =   StStr.strFalse;
            AutoCreateCompany.Order                     =   50;
            AutoCreateCompany.ExtendedGroupName         =   extgrp;
            AutoCreateCompany.EnglishName               =   "Create Parent Account";
            AutoCreateCompany.Description               =   "When checked the nonexisting parent account are automatically created, else the parent account name is lost";
            bSettings.AddSetting(AutoCreateCompany);

            SettingItemSpecial AutoCreatePrimaryContact =   new SettingItemSpecial(AStr.AutoCreatePrimaryContact,new BooleanDataType());
            AutoCreatePrimaryContact.Required           =   false;
            AutoCreatePrimaryContact.ResourceFile       =   resFile;
            AutoCreatePrimaryContact.Value              =   StStr.strFalse;
            AutoCreatePrimaryContact.Order              =   60;
            AutoCreatePrimaryContact.ExtendedGroupName  =   extgrp;
            AutoCreatePrimaryContact.EnglishName        =   "Create Primary Contact";
            AutoCreatePrimaryContact.Description        =   "When checked the non existing primary contact is automatically created, else the primary contact is lost";
            bSettings.AddSetting(AutoCreatePrimaryContact);

            SettingItemSpecial AutoGen                  =   new SettingItemSpecial(AStr.AutoGen,new BooleanDataType());
            AutoGen.Required                            =   false;
            AutoGen.ResourceFile                        =   resFile;
            AutoGen.Value                               =   StStr.strFalse;
            AutoGen.Order                               =   70;
            AutoGen.ExtendedGroupName                   =   extgrp;
            AutoGen.EnglishName                         =   "Auto generator mode";
            AutoGen.Description                         =   "When checked will allow generating as many records as asked.";
            bSettings.AddSetting(AutoGen);
        }

        /// <summary>
        /// Used to set the display value in ModuleOwner when loaded from DB
        /// </summary>
        void ModuleOwner_SettingItemsEvent(object sender, SettingItemsEventArgs e)
        {
            if ( e.EventType != SettingItemsEventType.Loaded )
                return;
            if ( ModuleTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmInputAccount ModuleOwner_SettingItemsEvent Guid: {0}", e.Data),ModuleTraceSwitch.Sw.Info);
            Guid custId                 =   new Guid((string)e.Data);
            if ( custId == Guid.Empty )
                return;
            ADNDynSystemUser dynac      =    DynEntity.GetFromCache<ADNDynSystemUser>(CrmStr.systemuser,Wrapper,new ResetWrapperHandler(ResetWrapper),custId);
            WSListDataType defAcc       =   (WSListDataType )((SettingItem)sender).DataType;
            defAcc.DisplayTextValue     =   dynac.fullname;
            if ( ModuleTraceSwitch.Sw.TraceVerbose )
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmInputAccount ModuleOwner_SettingItemsEvent END name: {0}", dynac.name),ModuleTraceSwitch.Sw.Info);
        }
    }

    /// <summary>  
    ///	Dedicated input module fo accounts
    /// </summary>
    public partial class CrmInputAccount : PortalCrmProgressModuleControl
    {

        #region General implementation

        public override Guid GuidID
        {
            get
            {
                return new Guid("{53D45BCD-F66F-4029-A7C5-F915F7A6430C}");
            }
        }
        #endregion General implementation

        /// <summary>
        /// Ctor
        /// </summary>
        public CrmInputAccount()
        {
            // Validators : name Ok
            ValidationGroup                             =   "Main";

        }

        public override string ExtendedResourcesGroup 
		{
            get
            {
                const string extgrp                         =   "INPUTCRMACCOUNT";
                 return extgrp;
            }
		}

        public override void InitPortalModuleControl(ModuleSettingsDictionary bSettings)
        {
            PortalModuleInitializer =   new CrmInputAccountSI(bSettings,this);
        }

        /// <summary>
        ///  The Page_Load event handler on this User Control is used to
        /// to load the list of the questions and civilities  
        /// </summary>
        protected void Page_Load(object sender, EventArgs e)
        {
            if (ModuleTraceSwitch.Sw.TraceVerbose)
                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmInputAccount Page_Load isPostBack: {0}",IsPostBack),ModuleTraceSwitch.Sw.Info);
            bool autogen                        =   Settings[AStr.AutoGen].ToBool();
            ModuleProgressArea                  =   RadProgressArea1;
            // init localization string in progress manager/area
            if (autogen )
                InitProgress(); // Pb no persist between postback
            if (!IsPostBack)
            {
                if ( autogen )
                {
                    pnlAutoGen.Visible              =   true;
                }
                Style nst                           =   new Style();
                nst.ForeColor                       =   Color.Red;
                
                lblName.ForeColor                   =   Color.Red;
                
                // If email field is mandatory, we set a validator on it
                if (Settings[AStr.EmailMandatory].ToBool())
                {
                    RFVEmail.Enabled                =   true;
                    lblEmailaddress1.ApplyStyle(nst);
                }
                else RFVEmail.Enabled               =   false;
                // Should Address contain values
                if (Settings[AStr.AddressMandatory].ToBool())
                {
                    RFVAddress.Enabled              =   true;
                    lblAdress1_name.ApplyStyle(nst);

                    REVCodePostale.Enabled          =   true;
                    lblAddress1_postalcode.ApplyStyle(nst);

                    REVCity.Enabled                 =   true;
                    lblAddress1_city.ApplyStyle(nst);

                    REVCountry.Enabled              =   true;
                    lblAddress1_country.ApplyStyle(nst);
                }
                else
                {
                    RFVAddress.Enabled              =   false;
                    REVCodePostale.Enabled          =   false;
                    REVCity.Enabled                 =   false;
                    REVCountry.Enabled              =   false;
                }

            }
        }

        /// <summary>
        /// Tasks to do:
        /// 0) validate datas
        /// 1) Insert record in CRM
        /// 2) insert record in DB
        /// </summary>
        void CrmInputAccount_ADNUpdateModule(object sender, ModuleEventArgs e)
        {
            // Should Email contain values
            if (Settings[AStr.EmailMandatory].ToBool())
                Page.Validate("Email");
            // Should Address contain values
            if (Settings[AStr.AddressMandatory].ToBool())
                Page.Validate("Address");
            if (!Page.IsValid)
            {
                if (ModuleTraceSwitch.Sw.TraceVerbose)
                    Trace2.WriteLine( "[V]CrmInputAccount CrmInputAccount_ADNUpdateModule : Page not valid",ModuleTraceSwitch.Sw.Info);
                e.Cancel            =   true;
                return;
            }
            bool autogen                        =   Settings[AStr.AutoGen].ToBool();
            Guid CrmAccountId                   =   Guid.Empty;
            int count                           =   0;
            int maxCount                        =   1;
            if ( autogen && tbMaxRecords.Value.HasValue )
                maxCount                            =   (int)tbMaxRecords.Value.Value;
            // If the Company Name is not empty checks the existence of the company
            string searchedCompany0                 =   RadtxtCompanyName.Text.Trim();
            string searchedContact0                 =   RadtxtPrimaryContact.Text.Trim();
            string name0                            =   RadtxtName.Text.Trim();
            bool createParent                       =   Settings[AStr.AutoCreateCompany].ToBool();
            bool createContact                      =   Settings[AStr.AutoCreatePrimaryContact].ToBool();
            try
            {
                if ( autogen )
                {
                    ProgressPrimaryTotal = maxCount;
                    ProgressTotalSteps = 0;
                    StartProgress();
                    ResetProgressSecTotal(maxCount);
                }
                string fmtCompany                   =   searchedCompany0+"-{1:D3}";
                if ( searchedCompany0.IndexOf("{0}") > -1 )
                    fmtCompany                      =   searchedCompany0;
                string fmtContact                   =   searchedContact0+"-{1:D3}";
                if ( searchedContact0.IndexOf("{0}") > -1 )
                    fmtContact                      =   searchedContact0;
                string fmtAccount                   =   name0+"-{1:D3}";
                if ( name0.IndexOf("{0}") > -1 )
                    fmtAccount                      =   name0;
                while ( count < maxCount )
                {
                    string searchedCompany          =   ( autogen ) ? string.Format(fmtCompany,count) : searchedCompany0;
                    bool parentCreated              =   false;
                    if ( searchedCompany != string.Empty )
                    {
                        ADNDynAccount s             =   Wrapper.Util.FindAccountByName(searchedCompany,createParent,ref parentCreated);
                        if ( s != null )
                            CrmAccountId            =   s.accountid;
                    }

                    Guid CrmPrimContactId           =   Guid.Empty;
                    // If the Primary Contact Name is not empty checks the existence of the contact
                    bool contactCreated             =   false;
                    ADNDynContact pContact          =   null;
                    string searchedContact          =   ( autogen ) ? string.Format(fmtContact,count) : searchedContact0;
                    if ( searchedContact != string.Empty )
                    {
                        pContact                    =   Wrapper.Util.FindContactByName(searchedContact,createContact,ref contactCreated);
                        if ( pContact != null )
                            CrmPrimContactId        =   pContact.contactid;
                    }

                    // Add new Account 
                    string name                     =   ( autogen ) ? string.Format(fmtAccount,count) : name0;
                    ADNDynAccount im                =   new ADNDynAccount(Wrapper,name);
                    im.SetOwnerFromUserId();
                    im.emailaddress1                =   RadtxtEmailaddress1.Text.Trim();
                    im.address1_line1               =   RadtxtAddress1_line1.Text.Trim();
                    im.address1_line2               =   Radtxtaddress1_line2.Text.Trim();
                    im.address1_line3               =   Radtxtaddress1_line3.Text.Trim();
                    im.address1_city                =   RadtxtAddress1_city.Text.Trim();
                    im.address1_country             =   RadtxtAddress1_country.Text.Trim();
                    im.address1_county              =   RadtxtAddress1_county.Text.Trim();
                    im.address1_postalcode          =   RadtxtAddress1_postalcode.Text.Trim();
                    im.telephone1                   =   RadtxtTelephone1.Text.Trim();
                    im.fax                          =   RadtxtFax.Text.Trim();
                    im.description                  =   RadTextSubject.Text.Trim();

                    if ( CrmAccountId != Guid.Empty )
                    {
                        if ( ModuleTraceSwitch.Sw.TraceVerbose )
                            Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"V]CrmInputAccount CrmInputAccount_ADNUpdateModule CrmAccountId: {0}",CrmAccountId),ModuleTraceSwitch.Sw.Info);
                        im.parentaccountid          =   CrmAccountId;
                    }

                    if ( CrmPrimContactId != Guid.Empty )
                    {
                        if ( ModuleTraceSwitch.Sw.TraceVerbose )
                            Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"V]CrmInputAccount CrmInputAccount_ADNUpdateModule CrmPrimContactId: {0}",CrmPrimContactId),ModuleTraceSwitch.Sw.Info);
                        im.primarycontactid         =   CrmPrimContactId;
                    }


                    // Create in CRM using web service
                    try
                    {
                        Guid AccountID              =   im.adminCreate();
                        if ( ModuleTraceSwitch.Sw.TraceVerbose )
                            Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmInputAccount CrmInputAccount_ADNUpdateModule Account created Accountid: {0}",AccountID),ModuleTraceSwitch.Sw.Info);
                    }
                    catch ( Exception ex )
                    {
                        if ( ModuleTraceSwitch.Sw.TraceError )
                            Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]CrmInputAccount CrmInputAccount_ADNUpdateModule Adding Account ex :{0}",ex),ModuleTraceSwitch.Sw.Info);
                        throw;
                    }
                    if ( autogen )
                    {
                        ProgressSecCount            +=  1;
                        SetUpdateProgress(name,ProgressPrimCount,ProgressSecCount);
                    }

                    // Assign to default owner
                    if ( Settings[AStr.AssignToOwner].ToBool() )
                    {
                        try
                        {
                            Guid ownerid            =   Settings[AStr.CrmInputAccountOwner].ToGuid();
                            if ( ModuleTraceSwitch.Sw.TraceVerbose )
                                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmInputAccount CrmInputAccount_ADNUpdateModule  assigning Account to owner id: '{0}'",ownerid),ModuleTraceSwitch.Sw.Info);
                            im.adminAssign(ownerid);
                            if ( ModuleTraceSwitch.Sw.TraceVerbose )
                                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmInputAccount CrmInputAccount_ADNUpdateModule Account assigned to owner id: '{0}'",ownerid),ModuleTraceSwitch.Sw.Info);
                        }
                        catch ( Exception ex )
                        {
                            if ( ModuleTraceSwitch.Sw.TraceError )
                                Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]CrmInputAccount CrmInputAccount_ADNUpdateModule assigning Account ex :{0}",ex),ModuleTraceSwitch.Sw.Info);
                            throw;
                        }
                    }
                    //update the contact
                    if ( contactCreated )
                    {
                        pContact.emailaddress1      =   RadtxtEmailaddress1.Text.Trim();
                        pContact.address1_line1     =   RadtxtAddress1_line1.Text.Trim();
                        pContact.address1_line2     =   Radtxtaddress1_line2.Text.Trim();
                        pContact.address1_line3     =   Radtxtaddress1_line3.Text.Trim();
                        pContact.address1_city      =   RadtxtAddress1_city.Text.Trim();
                        pContact.address1_country   =   RadtxtAddress1_country.Text.Trim();
                        pContact.address1_county    =   RadtxtAddress1_county.Text.Trim();
                        pContact.address1_postalcode = RadtxtAddress1_postalcode.Text.Trim();
                        pContact.telephone1         =   RadtxtTelephone1.Text.Trim();
                        pContact.fax                =   RadtxtFax.Text.Trim();
                        pContact.parentcustomerid   =   im.accountid;
                        pContact.adminUpdate();
                    }
                    count++;
                }
                clean();
            }
            catch ( Exception ex )
            {
                if ( ModuleTraceSwitch.Sw.TraceError )
                    Trace2.WriteLine( string.Format(CultureInfo.InvariantCulture,"CrmInputAccount CrmInputAccount_ADNUpdateModule ex :{0}",ex),ModuleTraceSwitch.Sw.Info);
                throw;
            }
            finally
            {
                if ( autogen )
                    EndProgress();
            }
        }
        
        /// <summary>
        /// clean : re-initialized fields 
        /// </summary>
        protected void clean()
        {
            RadtxtName.Text                 = string.Empty;
            RadtxtCompanyName.Text          = string.Empty;
            RadtxtPrimaryContact.Text       = string.Empty;
            RadtxtEmailaddress1.Text        = string.Empty;
            RadtxtAddress1_line1.Text       = string.Empty;
            Radtxtaddress1_line2.Text       = string.Empty;
            Radtxtaddress1_line3.Text       = string.Empty;
            RadtxtAddress1_city.Text        = string.Empty;
            RadtxtAddress1_country.Text     = string.Empty;
            RadtxtAddress1_county.Text      = string.Empty;
            RadtxtAddress1_postalcode.Text  = string.Empty;
            RadtxtTelephone1.Text           = string.Empty;
            RadtxtFax.Text                  = string.Empty;
            RadTextSubject.Text             = string.Empty;
        }

        public override void Page_PreInit(object sender, EventArgs e)
        {
            base.Page_PreInit(sender, e);
            string str          =   Helpers.LocalizeHelper.GetCurrentNeutralCultureName();
            updateBtn.SkinID    =   "Update_" + str;
            ResetBtn.SkinID     =   "Reset_" + str;
        }

        /// <summary>
        /// Reset the listbox to values from the fields grid
        /// </summary>
        void ResetBtn_Click(object sender, ImageClickEventArgs e)
        {
            clean();
        }

        #region Std overrides

        override protected void OnInit(EventArgs e)
        {
            InitializeComponent();
            base.OnInit(e);
        }

        private void InitializeComponent()
        {
            Load            +=  new System.EventHandler(this.Page_Load);
            ADNUpdateModule +=  new PortalModuleEventHandler(CrmInputAccount_ADNUpdateModule);
            ResetBtn.Click  +=  new ImageClickEventHandler(ResetBtn_Click);
        }

        #endregion
    }
}
